// Created by Roman Novitsky on 22.04.2009


#region Imported Namespaces


using System;
using System.Collections;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

using WtfManager.Controls.Extensions;
using WtfManager.UIManager;


#endregion


namespace WtfManager.HierarchicalData
{
  public class TreeItemSelectionManager: SelectionManager
  {
    #region Fields


    public static readonly DependencyProperty SelectedItemPathProperty =
      DependencyProperty.RegisterAttached("SelectedItemPath", typeof(string), typeof(TreeItemSelectionManager),
                                          new PropertyMetadata(SelectedItemPathPropertyChanged));


    #endregion


    #region Methods


    private static void SelectedItemPathPropertyChanged(DependencyObject dependencyObject,
                                                        DependencyPropertyChangedEventArgs e)
    {
      var selectionManager = GetSelectionManager(dependencyObject) as TreeItemSelectionManager;

      if (selectionManager != null)
      {
        selectionManager.SelectItem((string)e.NewValue);
      }
    }


    private void SelectItem(string path)
    {
      if (ItemsControl is TreeView)
      {
        var treeView = (TreeView)ItemsControl;

        if (!string.IsNullOrEmpty(path))
        {
          treeView.SetSelectedItem(path, item => ((TreeItem)item).Name, '\\');
        }
      }
    }


    protected override void OnSelectionChanged()
    {
      if (SelectedValue is TreeItem)
      {
        var treeItem = (TreeItem)SelectedValue;
        SetSelectedItemPath(ItemsControl, treeItem.Path);
      }
    }


    protected override void OnItemsSourceChanged()
    {
      if (CurrentItemsSource != PreviousItemsSource)
      {
        ReadOnlyTreeItemsCollection currentItemsCollection = GetItemsCollection(CurrentItemsSource);
        ReadOnlyTreeItemsCollection previousItemsCollection = GetItemsCollection(PreviousItemsSource);

        if(currentItemsCollection != null)
        {
          foreach (TreeItem item in currentItemsCollection)
          {
            if (item.Children != previousItemsCollection)
            {
              continue;
            }

            SelectItem(item, true);
            return;
          }
        }
      }

      base.OnItemsSourceChanged();
    }


    private static ReadOnlyTreeItemsCollection GetItemsCollection(IEnumerable itemsSource)
    {
      var itemsCollection = itemsSource as ReadOnlyTreeItemsCollection; 

      if(itemsSource is CollectionView)
      {
        var collectionView = (CollectionView)itemsSource;
        itemsCollection = collectionView.SourceCollection as ReadOnlyTreeItemsCollection;
      }
      return itemsCollection;
    }


    public static void SetSelectedItemPath(DependencyObject element, string value)
    {
      if (element == null)
      {
        throw new ArgumentNullException("element");
      }

      element.SetValue(SelectedItemPathProperty, value);
    }


    public static string GetSelectedItemPath(DependencyObject element)
    {
      if (element == null)
      {
        throw new ArgumentNullException("element");
      }
      return (string)element.GetValue(SelectedItemPathProperty);
    }


    #endregion
  }
}